#!/usr/bin/env python
# -*- coding: utf-8 -*-

import io
import os
import sys
import gzip
import timeit
import traceback

timefunc = timeit.default_timer


def cgi_view(http_method_names, gzip_enable=False):
    def decorator(func):
        def wrapper():
            if 'GET' in http_method_names:
                http_method_names.append('HEAD')
            if os.environ['REQUEST_METHOD'] not in http_method_names:
                result = {'headers': {}, 'content': 'Method Not Allowed'}
            else:
                try:
                    now = timefunc()
                    result = func()
                    duration = (timefunc() - now) * 1000
                    result['headers']['X-Runtime'] = '%dms' % int(duration)
                except:
                    traceback.print_exc()
                    result = {'headers': {}, 'content': 'Error!'}
            headers = result['headers']
            content = result['content']

            if gzip_enable and 'gzip' in os.environ.get('HTTP_ACCEPT_ENCODING', '') and len(content) > 256:
                gz_stream = io.BytesIO()
                gz_file = gzip.GzipFile(fileobj=gz_stream, mode='wb', compresslevel=6)
                gz_file.write(content)
                gz_file.close()
                content = gz_stream.getvalue()
                headers['Content-Encoding'] = 'gzip'
                headers['Vary'] = 'Accept-Encoding'
            headers.setdefault('Connection', 'keep-alive')
            headers.setdefault('Content-Type', 'text/plain; charset=utf-8')
            headers.setdefault('Content-Length', str(len(content)))
            headers.setdefault('X-Powered-By', 'Python CGI')

            for key in sorted(headers.keys()):
                sys.stdout.write('%s: %s\r\n' % (key, headers[key]))
            sys.stdout.write('\r\n')
            sys.stdout.write(content)
            sys.stdout.flush()
        return wrapper
    return decorator
